

#ifndef _FATFS
#define _FATFS	82786	

#ifdef __cplusplus
extern "C" {
#endif

#include "integer.h"	
#include "ffconf.h"		

#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif





#if _MULTI_PARTITION		
typedef struct {
	BYTE pd;	
	BYTE pt;	
} PARTITION;
extern PARTITION VolToPart[];	
#define LD2PD(vol) (VolToPart[vol].pd)	
#define LD2PT(vol) (VolToPart[vol].pt)	

#else							
#define LD2PD(vol) (BYTE)(vol)	
#define LD2PT(vol) 0			

#endif





#if _LFN_UNICODE			
#if !_USE_LFN
#error _LFN_UNICODE must be 0 in non-LFN cfg.
#endif
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif

#else						
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif

#endif





typedef struct {
	BYTE	fs_type;		
	BYTE	drv;			
	BYTE	csize;			
	BYTE	n_fats;			
	BYTE	wflag;			
	BYTE	fsi_flag;		
	WORD	id;				
	WORD	n_rootdir;		
#if _MAX_SS != 512
	WORD	ssize;			
#endif
#if _FS_REENTRANT
	_SYNC_t	sobj;			
#endif
#if !_FS_READONLY
	DWORD	last_clust;		
	DWORD	free_clust;		
	DWORD	fsi_sector;		
#endif
#if _FS_RPATH
	DWORD	cdir;			
#endif
	DWORD	n_fatent;		
	DWORD	fsize;			
	DWORD	volbase;		
	DWORD	fatbase;		
	DWORD	dirbase;		
	DWORD	database;		
	DWORD	winsect;		
	BYTE	win[_MAX_SS];	
} FATFS;





typedef struct {
	FATFS*	fs;				
	WORD	id;				
	BYTE	flag;			
	BYTE	pad1;
	DWORD	fptr;			
	DWORD	fsize;			
	DWORD	sclust;			
	DWORD	clust;			
	DWORD	dsect;			
#if !_FS_READONLY
	DWORD	dir_sect;		
	BYTE*	dir_ptr;		
#endif
#if _USE_FASTSEEK
	DWORD*	cltbl;			
#endif
#if _FS_LOCK
	UINT	lockid;			
#endif
#if !_FS_TINY
	BYTE	buf[_MAX_SS];	
#endif
} FIL;





typedef struct {
	FATFS*	fs;				
	WORD	id;				
	WORD	index;			
	DWORD	sclust;			
	DWORD	clust;			
	DWORD	sect;			
	BYTE*	dir;			
	BYTE*	fn;				
#if _USE_LFN
	WCHAR*	lfn;			
	WORD	lfn_idx;		
#endif
} DIR;





typedef struct {
	DWORD	fsize;			
	WORD	fdate;			
	WORD	ftime;			
	BYTE	fattrib;		
	TCHAR	fname[13];		
#if _USE_LFN
	TCHAR*	lfname;			
	UINT 	lfsize;			
#endif
} FILINFO;





typedef enum {
	FR_OK = 0,				
	FR_DISK_ERR,			
	FR_INT_ERR,				
	FR_NOT_READY,			
	FR_NO_FILE,				
	FR_NO_PATH,				
	FR_INVALID_NAME,		
	FR_DENIED,				
	FR_EXIST,				
	FR_INVALID_OBJECT,		
	FR_WRITE_PROTECTED,		
	FR_INVALID_DRIVE,		
	FR_NOT_ENABLED,			
	FR_NO_FILESYSTEM,		
	FR_MKFS_ABORTED,		
	FR_TIMEOUT,				
	FR_LOCKED,				
	FR_NOT_ENOUGH_CORE,		
	FR_TOO_MANY_OPEN_FILES,	
	FR_INVALID_PARAMETER	
} FRESULT;






FRESULT f_mount (BYTE vol, FATFS* fs);								
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);				
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);			
FRESULT f_lseek (FIL* fp, DWORD ofs);								
FRESULT f_close (FIL* fp);											
FRESULT f_opendir (DIR* dj, const TCHAR* path);						
FRESULT f_readdir (DIR* dj, FILINFO* fno);							
FRESULT f_stat (const TCHAR* path, FILINFO* fno);					
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);	
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs);	
FRESULT f_truncate (FIL* fp);										
FRESULT f_sync (FIL* fp);											
FRESULT f_unlink (const TCHAR* path);								
FRESULT	f_mkdir (const TCHAR* path);								
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask);			
FRESULT f_utime (const TCHAR* path, const FILINFO* fno);			
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new);	
FRESULT f_chdrive (BYTE drv);										
FRESULT f_chdir (const TCHAR* path);								
FRESULT f_getcwd (TCHAR* buff, UINT len);							
FRESULT	f_getlabel (const TCHAR* path, TCHAR* label, DWORD* sn);	
FRESULT	f_setlabel (const TCHAR* label);							
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf);	
FRESULT f_mkfs (BYTE vol, BYTE sfd, UINT au);						
FRESULT	f_fdisk (BYTE pdrv, const DWORD szt[], void* work);			
int f_putc (TCHAR c, FIL* fp);										
int f_puts (const TCHAR* str, FIL* cp);								
int f_printf (FIL* fp, const TCHAR* str, ...);						
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp);						

#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)

#ifndef EOF
#define EOF (-1)
#endif








#if !_FS_READONLY
DWORD get_fattime (void);
#endif


#if _USE_LFN							
WCHAR ff_convert (WCHAR chr, UINT dir);	
WCHAR ff_wtoupper (WCHAR chr);			
#if _USE_LFN == 3						
void* ff_memalloc (UINT msize);			
void ff_memfree (void* mblock);			
#endif
#endif


#if _FS_REENTRANT
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj);	
int ff_req_grant (_SYNC_t sobj);				
void ff_rel_grant (_SYNC_t sobj);				
int ff_del_syncobj (_SYNC_t sobj);				
#endif










#define	FA_READ				0x01
#define	FA_OPEN_EXISTING	0x00
#define FA__ERROR			0x80

#if !_FS_READONLY
#define	FA_WRITE			0x02
#define	FA_CREATE_NEW		0x04
#define	FA_CREATE_ALWAYS	0x08
#define	FA_OPEN_ALWAYS		0x10
#define FA__WRITTEN			0x20
#define FA__DIRTY			0x40
#endif




#define FS_FAT12	1
#define FS_FAT16	2
#define FS_FAT32	3




#define	AM_RDO	0x01	
#define	AM_HID	0x02	
#define	AM_SYS	0x04	
#define	AM_VOL	0x08	
#define AM_LFN	0x0F	
#define AM_DIR	0x10	
#define AM_ARC	0x20	
#define AM_MASK	0x3F	



#define CREATE_LINKMAP	0xFFFFFFFF






#if _WORD_ACCESS == 1	
#define	LD_WORD(ptr)		(WORD)(*(WORD*)(BYTE*)(ptr))
#define	LD_DWORD(ptr)		(DWORD)(*(DWORD*)(BYTE*)(ptr))
#define	ST_WORD(ptr,val)	*(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define	ST_DWORD(ptr,val)	*(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else					
#define	LD_WORD(ptr)		(WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define	LD_DWORD(ptr)		(DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
#define	ST_WORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define	ST_DWORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif

#ifdef __cplusplus
}
#endif

#endif 

